今天動手來實作過濾器 Filter 通常用來 format model 的格式,功能上有點類似 computed
因此我們可以利用 Filter 制定系統中常用的 format
import Vue 並使用 filter 來設計,
參數一 | 參數二 |
---|---|
filter name | function |
import Vue from 'vue';
Vue.filter('filterName', function(value) {
//custom format
return value.do.some.
});
使用的時候在 bind 的 model 後面使用加上 |
之後再放上 filter name
<p>{{ data | filterName }}</p>
在顯示之前,會透過 filter 過濾格式。
import Vue from 'vue';
Vue.filter('currency', function (num) {
return '$ ' + num.toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1, ");
});
Vue.filter('lowercase', (str) => str.toLowerCase() );
// Letter Grade & GPA
function letterGrade (score) {
if (score > 100 || score < 0) {
return '--';
}
else if (score >= 90) {
return 'A';
}
else if (score >= 80) {
return 'B';
}
else if (score >= 70) {
return 'C';
}
else if (score >= 60) {
return 'D';
}
else {
return 'F';
}
}
Vue.filter('letterGrade', letterGrade);
Vue.filter('gpa', (score) => {
const _score = letterGrade(score);
const gpa = {
A: '4.0',
B: '3.0',
C: '2.0',
D: '1.0',
F: '0.0',
}
return gpa[ _score ] || _score;
});
<template>
<div class="container">
<h1>Vue Filter</h1>
<hr>
<div class="row">
<div class="col-md-4">
<h2>currency:</h2>
<input type="number" v-model="demoCurrency" />
<h3>{{ demoCurrency | currency}}</h3> <!-- 過濾貨幣 -->
</div>
<div class="col-md-4">
<h2>lowercase:</h2>
<input type="text" v-model="demoLowerCase" />
<h3>{{ demoLowerCase | lowercase}}</h3> <!-- 過濾小寫 -->
</div>
<div class="col-md-4">
<h2>Letter Grade:</h2>
<input type="number" v-model="demoScore" />
<h3>{{ demoScore | letterGrade}}
<small>GPA: ( {{ demoScore | gpa }} )</small><!-- 過濾 GPA -->
</h3> <!-- 過濾 Letter Grade -->
</div>
</div>
<hr>
<h3>學期分數:</h3>
<table class="table">
<thead>
<tr>
<th>name</th>
<th>Letter Grade</th>
<th>score</th>
<th>GPA</th>
</tr>
</thead>
<tbody>
<tr v-for="item in scoreList">
<td>{{ item.name }}</td>
<td>{{ item.score | letterGrade}}</td><!-- 過濾 Letter Grade -->
<td>{{ item.score }}</td>
<td>{{ item.score | gpa}}</td><!-- 過濾 GPA -->
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
data() {
return {
demoCurrency: 1000,
demoLowerCase: 'LOWER CASE',
demoScore: 99,
scoreList: [
{name: 'jacky', score: 100},
{name: 'momo', score: 90},
{name: 'jasper', score: 89},
{name: 'eason', score: 80},
{name: 'mars', score: 79},
{name: 'mike', score: 70},
{name: 'ben', score: 69},
{name: 'Aaron', score: 60},
{name: 'mary', score: 59},
],
};
},
};
</script>
在 Vue 1.x 的時候其實官方有制定許多個 filter 供開發者使用,
到了 Vue 2.x 官方移除了這些 filter 種種原因在這篇討論中:
[Suggestion] Vue 2.0 - Bring back filters please #2756
{{ data | filter1:data2 | filter2 | filter3 | WTF }}
angular 時代真的很容易也很愛開發那種 filter..
後面維護的同事看了表示香菇..debug 看過.. 改一個 model 然後 filter 算了 30000 次..
看完了 filter 的優缺點,目前使用上不多,
大部分都是像範例上這種簡單,不複雜計算的格式轉換,
這些格式轉換往往是需求的關係,所以在最後顯示之前過濾成需求的格式既可。
不會動到後端原始資料,設定的時候也不需要轉回原本格式,相當方便。
另外就是因為使用了 vuex
在有些狀況可以寫好 format function 如範例中: letterGrade
我們在 getter 的時候.. 先經過 letterGrade 過濾在把資料回傳,
因此 UI 就不用煩惱要在哪個流程 format,取得資料的時候就過濾好囉。
filter
,getter
共用一個函式統一維護。
實作小範例入門 Vue & Vuex 2.0 - github 完整範例
使用 git checkout 切換每天範例。